package com.tarena.elts.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.tarena.elts.entity.EntityContext;
import com.tarena.elts.service.ExamService;
import com.tarena.elts.service.ExamServiceImp;
import com.tarena.elts.util.Config;

public class ExamServer {
	private Config config;
	Map<String, ExamService> serviceMap=new HashMap<String, ExamService>();
	private EntityContext entityContext;
	public void setEntityContext(EntityContext entityContext) {
		this.entityContext = entityContext;
	}
	public ExamServer(){}
	public void setConfig(Config config) {
		this.config = config;
	}
	public void start(){
		int port = config.getInt("ServerPort");
		try {
			ServerSocket ss = new ServerSocket(port);
			while(true){
				Socket s =ss.accept();
				new Service(s).start();
			}
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	class Service extends Thread{
		Socket s;
		public Service(Socket s){
			this.s=s;
		}
		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				ObjectInputStream in = new ObjectInputStream(s.getInputStream());
				Request req = (Request)in.readObject();
				ExamService service = getService(req);
				Response res = Utils.call(service,req);
				//服务器端必须把客户端发送来的sessionid响应回客户端
				res.setSessionID(req.getSessionID());
				ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
				out.writeObject(res);
				s.close();
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}
	private ExamService getService(Request req){
		String sid = req.getSessionID();
		if(sid==null){
			sid=UUID.randomUUID().toString();
			req.setSessionID(sid);
		}
		ExamService service = serviceMap.get(sid);
		if(service==null){
			ExamServiceImp serviceImp = new ExamServiceImp();
			serviceImp.setEntityContext(entityContext);
			serviceMap.put(sid, serviceImp);
			service=serviceImp;
		}
		return service;
	}
	public static void main(String[] args){
		ExamServer server = new ExamServer();
		Config config = new Config("server.properties");
		EntityContext entityContext = new EntityContext(config);
		server.setConfig(config);
		server.setEntityContext(entityContext);
		server.start();
	}
}
